package com.xbstar.wei.service2;

import java.math.BigInteger;
import java.security.MessageDigest;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;


import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;
import org.json.JSONException;
import org.json.JSONObject;



import com.xbstar.wei.service2.Message.MsgContent;
import com.xbstar.wei.service2.Message.MsgType;





public class WeixinUtil {
	public static JFAPIXml2Map xml2Map=new JFAPIXml2Map();
	public static String TOKEN=APPProperties.TOKEN;
	
	//HttpSession session;
	public WeixinUtil(){
		super();
		//xml2Map=new JFAPIXml2Map();
	}
	/**
	 * 实现微信验证信息sh1加密
	 * @param key
	 * @return 16位明文
	 */
	public static String sha1(String key) {
		try {
			MessageDigest md = MessageDigest.getInstance("SHA1");
			md.update(key.getBytes());
			String pwd = new BigInteger(1, md.digest()).toString(16);
			return pwd;
		} catch (Exception e) {
			e.printStackTrace();
			return key;
		}
	}
	/**
	 * 返回一个符合格式的news类型的item项(不包含item字段)
	 * @param Description 图片描述
	 * @param Title 图文信息标题（不可为空）
	 * @param PicUrl 图片链接(不可为空)
	 * @param Url 链接地址
	 * @return
	 */
	public static HashMap<String, String> itemFormatOfNews(String Description,String Title,String PicUrl,String Url ) {
		if(Title==null||PicUrl==null){
			return null;
		}
		HashMap<String, String>item=new HashMap<String, String>();
		item.put(Message.MsgContent.Title, Title==null?"":Title);
		item.put(Message.MsgContent.Description, Description==null?"":Description);
		item.put(Message.MsgContent.PicUrl, PicUrl==null?"":PicUrl);
		item.put(Message.MsgContent.Url, Url==null?"":Url);
		
		return item;
	}
	/**
	 * 通过code获取用户基本信息（包含access_token,openid,过期时间）
	 * @param code
	 * @return 用户基本信息，
	 * @throws Exception 
	 */
	public JSONObject getAcessTokenJsonByCode(String code) throws Exception{
		String url=WeiURL.getSnsapi_baseUrlByCode(code);
		return send2WeiByGetMethod(url);
		
	}
	/**
	 * 通过code获取用户基本信息（包含access_token,openid,过期时间）
	 * @param code
	 * @return 用户基本信息，
	 * @throws Exception 
	 */
	@Deprecated
	public JSONObject getUserAccessTokenMapByCode(String code) throws Exception {
		String url=WeiURL.getSnsapi_baseUrlByCode(code);
		HttpClient client=SSLUtils.createHttpsClient();
		HttpGet gtGet=new HttpGet(url);
		JSONObject object=null;
		HttpEntity entity=null;
		try {
			HttpResponse response=client.execute(gtGet);
			if (response!=null&&response.getStatusLine().getStatusCode()==HttpStatus.SC_OK) {
				entity=response.getEntity();
			}else {
				Exception ee=new Exception("获取网络状态不对--获取access_token失败");
				throw ee;
			}
		}catch (Exception e) {
			throw e;
		}
		try {
			String strJ=EntityUtils.toString(entity);
			object= new JSONObject(strJ);
			return object;
		} catch (Exception e) {
			throw e;
		}
	}
	/**
	 * 通过accesstoken和openid获取用户的详细信息，包含昵称，头像，所在地区。。
	 * @param actoken access_token,通过code换取得到
	 * @param openid  通过code获取用户唯一编号。
	 * @return 包含用户详细信息。
	 */
	public JSONObject getUserInfoFromWeiByAccessTokenAndOpenid(String actoken,String openid){
		String url=WeiURL.getUserInfoByAccessTokenUri(actoken,openid);
		JSONObject result=null;
		try{
			result=send2WeiByGetMethod(url);
			
		}
		catch(Exception ex){
			ex.printStackTrace();
		}
		return result;
	}
	/**
	 * 向微信服务器发送get方法
	 * @param url 配置好参数的url
	 * @return 从微信服务器返回的值
	 * @throws Exception
	 */
	public static JSONObject send2WeiByGetMethod(String url) throws Exception{
		HttpClient client=SSLUtils.createHttpsClient();
		HttpGet get=new HttpGet(url);
		try {
			HttpResponse response=client.execute(get);
			if (response.getStatusLine().getStatusCode()==HttpStatus.SC_OK ) {
				HttpEntity entity=response.getEntity();
				try {
					String str=EntityUtils.toString(entity,"UTF-8");
					JSONObject json=new JSONObject(str);
					int num=-1;
					try {
						num=json.getInt("errcode");
					} catch (Exception e) {
						System.out.println("没有errcode这个字段");
					}
					if (num!=0) {
						if(num!=-1){
							client.getConnectionManager().shutdown();	
							throw new Exception("错误编码： "+json.getInt("errcode")+" 错误参考信息： "+json.getString("errmsg"));
						}else {
							return json;
						}
					}else {
						return json;			
					}
				} catch (Exception e) {
					e.printStackTrace();
					client.getConnectionManager().shutdown();	
					System.out.println("获取的不是文件流或者转化成json失败");
					throw new Exception("获取的不是文件流或者转化成json失败");
				}
				
				
			}
			
		} catch (Exception e) {
			e.printStackTrace();
			client.getConnectionManager().shutdown();	
			System.out.println("网络连接错误");
			throw new Exception("网络连接错误");
		}       
		return null;
	}
	/**
	 * 采用post向微信服务器发送jsonobject对象的方法
	 * @param url 微信连接地址
	 * @obj obj 要发送的对象
	 * @return 返回从服务器中获得值
	 * @throws Exception 
	 */
	@Deprecated
	public static JSONObject send2WeiByPostMethod(String url,JSONObject obj) throws Exception {
		if (obj==null||url==null) {
			return null;
		}
		HttpClient client=new DefaultHttpClient();
		HttpPost post=new HttpPost(url);
		StringEntity json=new StringEntity(obj.toString(),"UTF-8");
		post.setEntity(json);
		HttpResponse response;
		try {
			 response =client.execute(post);
		} catch (Exception e) {
			Exception ee=new Exception("未能成功上传，可能网络问题，请检查网络后再次尝试！");
			throw ee;
		}
		if(response.getStatusLine().getStatusCode()!=HttpStatus.SC_OK ) {
			Exception ee=new Exception("网络配置头部有错，请检查确认");
			throw ee;
		}
		String str=EntityUtils.toString(response.getEntity());
		JSONObject object;
		try {
			object = new JSONObject(str);
		} catch (Exception e) {
			Exception ee=new Exception("获取的流转化为json失败");
			throw ee;
		}
		int numF=-1;
		try {
			numF=object.getInt("errcode");
		} catch (Exception e) {
			System.out.println("没有errcode这个字段");
		}
		if (numF!=0) {
			if (numF!=-1) {
				client.getConnectionManager().shutdown();	
				throw new Exception("错误编码： "+object.getInt("errcode")+" 错误参考信息： "+object.getString("errmsg"));
			}else {
				return obj;
			}
			
		}else {
			return object;
		}
		
	}
	/**
	 * 验证是否来自微信服务器
	 * @param request
	 * @return 来自微信服务器返回true，否则返回false
	 */
	
	public static boolean checkWeixinReques(HttpServletRequest request) {
		String signature = request.getParameter("signature");
		String timestamp = request.getParameter("timestamp");
		String nonce = request.getParameter("nonce");
		System.out.println("传进来的参数是：\n signature="+signature+"\n timestamp="+timestamp+"\n nonce="+nonce);
		if (signature != null && timestamp != null && nonce != null ) {
			String[] strSet = new String[] { TOKEN, timestamp, nonce };
			java.util.Arrays.sort(strSet);
			String key = "";
			for (String string : strSet) {
				key = key + string;
			}
			String pwd = WeixinUtil.sha1(key);
			System.out.println("加密后明文是："+pwd);
			return pwd.equals(signature);
		}else {
			return false;
		}
		
	}
	public static HashMap<String, Object> produceNewsMessege(
			HashMap<String, Object> map,
			ArrayList<HashMap<String, String>> articles) {
		HashMap<String, Object> resMap = new HashMap<String, Object>();
		resMap.put(MsgContent.FromUserName, map.get(MsgContent.ToUserName));
		resMap.put(MsgContent.ToUserName, map.get(MsgContent.FromUserName));
		long creattime=System.currentTimeMillis()/1000;
		resMap.put(MsgContent.CreateTime, creattime);
		resMap.put(MsgContent.MsgType,MsgType.News);
		resMap.put(MsgContent.ArticleCount, ""+articles.size());
		resMap.put(MsgContent.Articles, articles);
		return resMap;
	}
	
	public static String getAWeiXmlByMapString(HashMap<String, Object> resMap) {
		if (resMap==null) {
			return null;
		}
		JFAPIXml2Map transfer=new JFAPIXml2Map();
		return transfer.getAWeiXmlByMapString(resMap);
	}
	/**
	 * 生成文本信息
	 * @param map 
	 * @param content 文本内容
	 * @return 
	 */
	public static HashMap<String, Object> produceTextMessege(HashMap<String, Object>map,String content) {
		if (map==null) {
			return null;
		}
		HashMap<String, Object> resMap = new HashMap<String, Object>();
		resMap.put(Message.MsgContent.FromUserName, map.get(Message.MsgContent.ToUserName));
		resMap.put(Message.MsgContent.ToUserName, map.get(Message.MsgContent.FromUserName));
		long creattime=System.currentTimeMillis()/1000;
		resMap.put(Message.MsgContent.CreateTime, creattime);
		resMap.put(Message.MsgContent.MsgType, MsgType.Text);
		resMap.put(Message.MsgContent.Content, ""+content);
		return resMap;
		
	}
	/**
	 * 设置author2.0网页获得的request参数，并对其进行分析
	 * @param request
	 */
	private	HttpServletRequest _request;
	private boolean isAuthor=false;
	private String resultStr="";
	public void setNeedAuthorReuqest(HttpServletRequest request) {
		_request=request;
		Map<String,String[]>map=request.getParameterMap();
		if(map.containsKey("code")){
			isAuthor=true;
		}
		if(isAuthor==false){
			resultStr= "<h1>对不起您没有同意我们获取您的信息，<br/>我们将会以更加严格的使用与保存您的信息，请您放心<h1>";
		}else{
			HttpSession sess=request.getSession();
			String code1= map.get("code")[0];
			System.out.println("此处是code值，为："+code1);
			sess.setAttribute("code", code1);

			
		}
		
	}
	public boolean isAuthored() {
		return isAuthor;
	}
	@Deprecated
	public void setUserAuthorSession() {
	}
	/**
	 * 判断用户是否认证后的结果
	 * @return
	 */
	public String getResultString() {
		return resultStr;
	}
	public void setNeedAuthorReuqest(HttpServletRequest request,
			HttpSession session) {
		Map<String,String[]>map=request.getParameterMap();
		if(map.containsKey("code")){
			isAuthor=true;
		}
		if(isAuthor==false){
			resultStr= "<h1>对不起您没有同意我们获取您的信息，<br/>我们将会以更加严格的使用与保存您的信息，请您放心<h1>";
		}else{

			String code1= map.get("code")[0];
			session.setAttribute("code", code1);
			
		}
		
	}
	/**
	 * 通过code换取openid
	 * @param code
	 * @return  成功返回openid，否则null
	 */
	public static String getOpenIdByAuthorCode(String code) {
		if (code==null||code.equals("")) {
			System.out.println("传入的code值为空或者为null");
			return null;
		}
		String url=WeiURL.getSnsapi_baseUrlByCode(code);
		String openIdStr=null;
		try {
			JSONObject object=WeixinUtil.send2WeiByGetMethod(url);
			openIdStr=object.getString(Message.Access_Token.Openid);
			System.out.println("获得的用户openid是："+openIdStr);
			return openIdStr;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}
}
